<?php
/**
 * Used for ssl decryption
 */
namespace Cephalopod\SSL;

use Cephalopod\Tube;
use Cephalopod\Http;
use Exception;

class OptimizedUnpackTube implements Tube
{
    private SSLTube $sslTube;

    private string $privateKey;

    private string $httpBuffer = '';

    private int $more = -1;

    public function __construct()
    {
        $this->sslTube = new SSLTube();
    }

    public function setPrivateKey(string $privateKey)
    {
        $this->sslTube->setPrivateKey($privateKey);
    }

    public function dequeue(): string
    {
        while(true) {
            $this->handleMore();
            $result = Http::idealUnpacking($this->httpBuffer);
            $this->httpBuffer = $result['unknow_data'];
            if ($result['content_length'] < 0) {
                break;
            }
            $this->sslTube->enqueue($result['body']);
            $this->more = $result['more'] < 0 ? 0 : $result['more'];
        }
        return $this->sslTube->dequeue();
    }

    public function enqueue(string $binraryData)
    {
        $this->httpBuffer .= $binraryData;
    }

    private function handleMore()
    {
        if ($this->more > 0) {
            $bufferLength = strlen($this->httpBuffer);
            if ($bufferLength > $this->more) {
                $this->sslTube->enqueue(substr($this->httpBuffer, 0, $this->more));
                $this->httpBuffer = substr($this->httpBuffer, $this->more);
                $this->more = 0;
            } elseif ($bufferLength == $this->more) {
                $this->sslTube->enqueue($this->httpBuffer);
                $this->httpBuffer = '';
                $this->more = 0;
            } else {
                $this->sslTube->enqueue($this->httpBuffer);
                $this->httpBuffer = '';
                $this->more -= $bufferLength;
            }
        }
    }
}
